#include "app_dac.h"
#include "fr30xx.h"
#include "driver_psd_dac.h"
#include "system_fr30xx.h"
#include "y_ringbuf.h"
#include "FreeRTOS.h"
#include "task.h"
#include <math.h>
#include <stdio.h>
#include <string.h>

// 解决编译警告：添加 psd_dac_pll_divider 函数的显式声明
void psd_dac_pll_divider(uint32_t divider);

PSD_DAC_HandleTypeDef hpsd;

// 声明外部ringbuf引用，指向user_bt.c中的ringbuf
extern RINGBUF_st *s_audio_ringbuf;

// // 软件FIFO缓冲区 - 参考micropython版本
// static uint8_t s_audio_buffer[1024];
// static fifo_st s_audio_fifo_dev = {
//     .in = 0,
//     .len = 0,
//     .out = 0,
//     .buffer = s_audio_buffer,
//     .buffer_len = sizeof(s_audio_buffer),
// };

void app_dac_pa_init(void) {
    GPIO_InitTypeDef gpio_config;
    __SYSTEM_GPIOB_CLK_ENABLE();
    gpio_config.Pin = GPIO_PIN_12;
    gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_config.Pull = GPIO_PULLUP;
    gpio_config.Alternate = GPIO_FUNCTION_0;
    gpio_init(GPIOB, &gpio_config);
}

void app_dac_pa_ctrl(int en) {
    if (en == 0) {
        gpio_write_pin(GPIOB, GPIO_PIN_12, GPIO_PIN_CLEAR);  // 0时拉低
    } else {
        gpio_write_pin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);    // 1时拉高
    }
}
void psd_dac_irq(void)
{
    psd_dac_IRQHandler(&hpsd);
}
void app_dac_gpio_init(void) {
    __SYSTEM_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef CodecIO;
    CodecIO.Pin  = GPIO_PIN_6 | GPIO_PIN_7;
    CodecIO.Mode = GPIO_MODE_AF_PP;
    CodecIO.Pull = GPIO_PULLUP;
    CodecIO.Alternate = GPIO_FUNCTION_D;
    gpio_init(GPIOC, &CodecIO);
}

// 中断回调函数
void dac_leftempty_cb(struct __PSD_DAC_HandleTypeDef *hpsd){
    // 移除打印，避免在中断中打印过多信息
}

void dac_rightempty_cb(struct __PSD_DAC_HandleTypeDef *hpsd){
    // 移除打印，避免在中断中打印过多信息
}

// 定义DAC硬件FIFO触发中断的阈值（32个样本）
#define DAC_TRANSFER_SAMPLES    32
// 对应的字节数
#define DAC_TRANSFER_BYTES      (DAC_TRANSFER_SAMPLES * 2)

// 用于从软件FIFO传输到硬件FIFO的临时缓冲区
static int16_t dac_data[DAC_TRANSFER_SAMPLES];

// 中断频率检测变量
static uint32_t dac_isr_count = 0;
static uint32_t dac_isr_last_time = 0;
static uint32_t dac_isr_frequency = 0;

void dac_leftalmostempty_cb(struct __PSD_DAC_HandleTypeDef *hpsd){
    uint32_t read_len;
    UBaseType_t uxSavedInterruptStatus;

    // 中断频率检测
    dac_isr_count++;
    uint32_t current_time = xTaskGetTickCount() * portTICK_PERIOD_MS;
    
    // 每秒计算一次中断频率
    if (current_time - dac_isr_last_time >= 1000) {
        dac_isr_frequency = dac_isr_count;
        dac_isr_count = 0;
        dac_isr_last_time = current_time;
        
        // 计算理论中断频率
        // 48kHz采样率，每次中断处理32个样本
        // 理论中断频率 = 48000 / 32 = 1500 Hz
        uint32_t theoretical_freq = 48000 / 32;
        
        printf("DAC_ISR_FREQ: actual=%d Hz, theoretical=%d Hz, ratio=%.2f\r\n", 
               dac_isr_frequency, theoretical_freq, 
               (float)dac_isr_frequency / theoretical_freq);
        
        // 分析频率差异
        if (dac_isr_frequency > theoretical_freq * 1.1) {
            printf("DAC_ISR_WARNING: Interrupt frequency too HIGH!\r\n");
        } else if (dac_isr_frequency < theoretical_freq * 0.8) {
            printf("DAC_ISR_WARNING: Interrupt frequency too low! Audio may be slow.\r\n");
        } else {
            printf("DAC_ISR_OK: Interrupt frequency is normal\r\n");
        }
    }

    // 从ISR进入临界区，这是保护共享ringbuf的正确方法
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
    
    // 从ringbuf读取数据到临时缓冲区
    if (s_audio_ringbuf != NULL) {
        uint32_t available_bytes = y_ringbuf_get_used_size(s_audio_ringbuf);
        if (available_bytes >= DAC_TRANSFER_BYTES) {
            read_len = y_ringbuf_read_clear(s_audio_ringbuf, (uint8_t*)dac_data, DAC_TRANSFER_BYTES);
        } else {
            read_len = 0;
            // 添加调试信息
            static uint32_t debug_count = 0;
            debug_count++;
            if (debug_count % 5000 == 0) { // 从1000增加到5000，减少打印频率
                printf("DAC_ISR_DEBUG: available=%d, needed=%d\r\n", available_bytes, DAC_TRANSFER_BYTES);
            }
        }
    } else {
        read_len = 0;
    }
    
    // 从ISR退出临界区
    taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);

    // 如果从ringbuf读取的数据不足，说明发生了underrun，用静音数据填充
    if(read_len < DAC_TRANSFER_BYTES) {
        // 使用memset填充静音，比for循环更高效
        memset(dac_data, 0, sizeof(dac_data));
        
        // 减少underrun警告频率，避免打印过多
        static uint32_t underrun_count = 0;
        underrun_count++;
        if (underrun_count % 1000 == 0) { // 从100增加到1000，减少打印频率
            printf("DAC_UNDERRUN: read_len=%d, expected=%d\r\n", read_len, DAC_TRANSFER_BYTES);
        }
    }
    
    // 将数据写入DAC硬件FIFO - 修复数据格式转换
    for (int i = 0; i < DAC_TRANSFER_SAMPLES; i++) {
        // 修复：直接写入int16_t数据，不需要左移8位
        // DAC硬件期望的是16位有符号PCM数据
        __PSD_DAC_WRITE_FIFO_DATA_LEFT(dac_data[i]);
    }
    
    // 清除中断标志
    psd_dac_int_clr(PSD_DAC_INT_DACFF_L_AEMPTY);
}

void dac_rightalmostempty_cb(struct __PSD_DAC_HandleTypeDef *hpsd){
    // 单声道模式，右声道不需要处理
    psd_dac_int_clr(PSD_DAC_INT_DACFF_R_AEMPTY);
}

// 完整的DAC初始化函数（与可播放版本一致）
static void app_dac_psd_init(uint32_t sample_rate){
    printf("app_dac_psd_init: Starting PSD_DAC initialization...\r\n");
    
    // GPIO初始化
    __SYSTEM_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef CodecIO;
    CodecIO.Pin  = GPIO_PIN_6 | GPIO_PIN_7;
    CodecIO.Mode = GPIO_MODE_AF_PP;
    CodecIO.Pull = GPIO_PULLUP;
    CodecIO.Alternate = GPIO_FUNCTION_D;
    gpio_init(GPIOC, &CodecIO);
    printf("app_dac_psd_init: GPIO initialized\r\n");

    // 启用DAC时钟
    __SYSTEM_PSD_DAC_CLK_ENABLE();
    printf("app_dac_psd_init: DAC clock enabled\r\n");
    
    // 配置PSD_DAC参数
    memset(&hpsd, 0, sizeof(hpsd));
    
    hpsd.Init.DataSrc = PSD_DAC_DATA_SOURCE_DACFIFO;
    hpsd.Init.Right_mix = PSD_DAC_FUNC_DISABLE;
    hpsd.Init.Left_mix = PSD_DAC_FUNC_DISABLE;
    hpsd.Init.MonoEn = PSD_DAC_FUNC_ENABLE;
    
    // 关键修复：强制使用48kHz时钟源，无论输入采样率如何
    // 这样可以确保DAC硬件运行在正确的频率上
    hpsd.Init.ClockSource = PSD_DAC_CLOCK_SOURCE_24M_MODE;
    printf("app_dac_psd_init: FORCED 24MHz clock source for stable 48kHz operation\r\n");

    hpsd.Init.Swap = 0;
    
    // 强制使用48kHz硬件配置，无论输入采样率如何
    // 这样可以确保DAC中断频率正确
    enum_PSD_DAC_SampleRate_t dac_sample_rate = PSD_DAC_SAMPLE_RATE_48000;
    printf("app_dac_psd_init: FORCED 48kHz hardware config regardless of input sample rate\r\n");
    printf("app_dac_psd_init: This will fix the interrupt frequency issue\r\n");
    
    hpsd.Init.SampleRate = dac_sample_rate;
    
    // 添加详细的DAC配置信息
    printf("app_dac_psd_init: DAC SampleRate enum = %d (should be 5 for 48kHz)\r\n", dac_sample_rate);
    printf("app_dac_psd_init: ClockSource = %d (0=24MHz, 1=AUPLL, 2=External)\r\n", hpsd.Init.ClockSource);

    hpsd.Init.Oversampling_Level = PSD_DAC_OVERSAMPLING_LOW;
    hpsd.Init.DAC_DataFormat = PSD_DAC_FIFO_FORMAT_16BIT;
    
    // 关键修复：在初始化结构体中设置FIFO阈值
    // 这样psd_dac_init函数会自动设置FIFO阈值
    hpsd.Init.DAC_FIFOThreshold = 32; // 使用一个更安全的值
    hpsd.Init.DAC_FIFOCombine = PSD_DAC_FUNC_DISABLE; // 禁用FIFO合并模式
    
    // 设置中断回调函数
    hpsd.DAC_FIFO_LeftEmpty_Callback = dac_leftempty_cb;
    hpsd.DAC_FIFO_RightEmpty_Callback = dac_rightempty_cb;
    hpsd.DAC_FIFO_LeftAlmostEmpty_Callback = dac_leftalmostempty_cb;
    hpsd.DAC_FIFO_RightAlmostEmpty_Callback = dac_rightalmostempty_cb;
    printf("app_dac_psd_init: Callback functions set\r\n");
    
    // 先初始化PSD_DAC，再配置中断
    psd_dac_init(&hpsd);
    printf("app_dac_psd_init: PSD_DAC initialized\r\n");
    
    // 配置DAC参数
    psd_dac_mute_contrl(0);
    psd_dac_set_volume(PSD_DAC_CH_LR, 0x1000);
    
    // 验证FIFO阈值设置
    printf("app_dac_psd_init: DAC FIFO threshold set to %d (32 samples)\r\n", hpsd.Init.DAC_FIFOThreshold);
    
    // 计算理论中断频率
    uint32_t expected_isr_freq = 48000 / hpsd.Init.DAC_FIFOThreshold;
    printf("app_dac_psd_init: Expected ISR frequency = %d Hz (48kHz / %d)\r\n", expected_isr_freq, hpsd.Init.DAC_FIFOThreshold);
    
    // 清除所有中断标志
    psd_dac_int_clr(PSD_DAC_INT_DACFF_L_AEMPTY);
    psd_dac_int_clr(PSD_DAC_INT_DACFF_R_AEMPTY);
    psd_dac_int_clr(PSD_DAC_INT_DACFF_L_EMPTY);
    psd_dac_int_clr(PSD_DAC_INT_DACFF_R_EMPTY);
    psd_dac_int_clr(PSD_DAC_INT_DACFF_L_FULL);
    psd_dac_int_clr(PSD_DAC_INT_DACFF_R_FULL);
    printf("app_dac_psd_init: All interrupts cleared\r\n");
    
    // 配置中断优先级
    NVIC_SetPriority(PSD_DAC_IRQn, 5); // 使用较低优先级
    printf("app_dac_psd_init: Interrupt priority set\r\n");
    
    // 启用中断
    NVIC_EnableIRQ(PSD_DAC_IRQn);
    printf("app_dac_psd_init: NVIC interrupt enabled\r\n");
    
    // 启用almost empty中断
    psd_dac_int_enable(PSD_DAC_INT_DACFF_L_AEMPTY);
    printf("app_dac_psd_init: Almost empty interrupt enabled\r\n");
    
    printf("app_dac_psd_init: PSD_DAC initialization completed successfully!\r\n");
}

// 配置DAC采样率 - 此函数将被移除
/*
void app_dac_set_sample_rate(uint32_t sample_rate)
{
    printf("app_dac_set_sample_rate: %d Hz\r\n", sample_rate);
    
    // 根据采样率选择DAC配置
    enum_PSD_DAC_SampleRate_t dac_sample_rate;
    switch(sample_rate) {
        case 16000:
            dac_sample_rate = PSD_DAC_SAMPLE_RATE_16000;
            break;
        case 32000:
            dac_sample_rate = PSD_DAC_SAMPLE_RATE_32000;
            break;
        case 44100:
            dac_sample_rate = PSD_DAC_SAMPLE_RATE_44100;
            break;
        case 48000:
            dac_sample_rate = PSD_DAC_SAMPLE_RATE_48000;
            break;
        default:
            dac_sample_rate = PSD_DAC_SAMPLE_RATE_44100; // 默认44.1kHz
            printf("app_dac_set_sample_rate: Unsupported sample rate, using 44.1kHz\r\n");
            break;
    }
    
    // 重新配置DAC采样率
    hpsd.Init.SampleRate = dac_sample_rate;
    psd_dac_init(&hpsd); // 恢复调用，确保时钟分频器被正确设置
    printf("app_dac_set_sample_rate: DAC sample rate updated to %d Hz\r\n", sample_rate);
}
*/

void app_dac_init(uint32_t sample_rate) {
    printf("app_dac_init: Starting DAC initialization for %d Hz...\r\n", sample_rate);
    
    // // 初始化功放
    // app_dac_pa_init();
    // app_dac_pa_ctrl(1);  // 启用功放
    // printf("app_dac_init: Power amplifier enabled\r\n");
    
    // 初始化DAC硬件
    app_dac_psd_init(sample_rate);
    printf("app_dac_init: DAC hardware initialized\r\n");
    
    // 软件FIFO已在user_bt.c中初始化，无需重复初始化
    printf("app_dac_init: Software FIFO already initialized in user_bt.c\r\n");
    
    // 写入初始静音数据到DAC FIFO，启动播放 - 修复数据格式
    for (int i = 0; i < 32; i++) { // 更新为32个样本
        dac_data[i] = 0; // 静音值（对应有符号PCM 0）
    }
    // 修复：直接写入int16_t数据，不需要格式转换
    psd_dac_write_dac_fifo_left(dac_data, sizeof(dac_data)/sizeof(dac_data[0]));
    psd_dac_write_dac_fifo_left(dac_data, sizeof(dac_data)/sizeof(dac_data[0]));
    printf("app_dac_init: Initial silence data written to DAC FIFO\r\n");
    
    // 生成一个简单的测试音调验证DAC工作
    printf("app_dac_init: Generating test tone to verify DAC...\r\n");
    for (int i = 0; i < 32; i++) {
        // 生成1kHz正弦波测试音
        float freq = 1000.0f; // 1kHz
        float sample_rate = 48000.0f; // 48kHz
        float t = (float)i / sample_rate;
        int16_t sample = (int16_t)(sin(2.0f * 3.141592653f * freq * t) * 8000.0f); // 降低音量
        dac_data[i] = sample;
    }
    psd_dac_write_dac_fifo_left(dac_data, 32);
    printf("app_dac_init: Test tone written to DAC FIFO\r\n");
    
    printf("app_dac_init: DAC initialization completed successfully!\r\n");
}

void app_dac_gen_sin(void) {
    for (int i = 0; i < sizeof(dac_data)/sizeof(dac_data[0]); i++) {
        int tmp = sin((2 * 3.141592653 * i) / (sizeof(dac_data)/sizeof(dac_data[0]))) * 32767;
        // 修复：直接使用int16_t数据，不需要左移8位
        dac_data[i] = (int16_t)tmp;
    }
}

void app_dac_write_pcm(const int16_t *pcm, unsigned int len) {
    for (unsigned int i = 0; i < len && i < sizeof(dac_data)/sizeof(dac_data[0]); i++) {
        // 修复：直接使用int16_t数据，不需要左移8位
        dac_data[i] = pcm[i];
    }
    psd_dac_write_dac_fifo_left(dac_data, len > sizeof(dac_data)/sizeof(dac_data[0]) ? sizeof(dac_data)/sizeof(dac_data[0]) : len);
} 